iT邦幫忙

2021 iThome 鐵人賽

DAY 20
1

What is JWT?

JWT全名為JSON Web Token,是一種跨域認證的Solution,它規定了一種Token的架構,並目前多用於前後分離場景與OAuth2.0的業務場景之下。

一般而言,使用者註冊登入後會生成一個jwt token返回給瀏覽器,瀏覽器向服務端請求資料時攜帶 token ,伺服器端使用 signature 中定義的方式進行解碼,進而對token進行解析和驗證。

JWT Token組成部分

https://mdimg.wxwenku.com/getimg/ccdf080c7af7e8a10e9b88444af98393328aa2998e4a67674f788858dc9a91c02199e40fdfd2cf3372e53609b9dc12ed.jpg

JWT-Toke的組成

  • Header: 用來指定使用的Algorithm(HMAC SHA256 RSA)和token type(如JWT),並透過Base64進行編碼,範例如下
{
	"alg": "HS256",
	"typ": "JWT"
}
  • payload: 包含宣告(要求),宣告通常是使用者資訊或其他資料的宣告,比如User id, name, email等. 宣告可分為三種: registered, public, private,範例如下
{
  "_id": "<user_id>", 
  "name": "<user_name>",
  "email": "<user_email>"
}
  • signature: 用來保證JWT的真實性,可以使用不同的演算來加解密。為了得到signature部分,必須有編碼過的header和payload,以及一個祕鑰,簽名演算法使用header中指定的那個,然後對其進行簽名即可! 簽名是 用於驗證訊息在傳遞過程中有沒有被更改 ,並且,對於使用私鑰簽名的token,它還可以驗證JWT的傳送方是否為它所稱的傳送方。

header

{
    "alg": "HS256",
    "typ": "JWT"
}

對上面的json進行base64編碼即可得到JWT的第一個部分

payload

在 jwt.io 網站中,提供了一些JWT token的編碼,驗證以及生成jwt的工具。

下圖就是一個典型的jwt-token的組成部分。

https://ithelp.ithome.com.tw/upload/images/20211005/20129737DxK27T4ixt.png

Why we need JWT?

在以往的web中,我們通常以Cookie-Session模式來實現用戶登入,相關流程如下:

  1. 用戶在瀏覽器填寫帳號密碼並發送給伺服器端
  2. 服務端利用帳號密碼驗證,驗證通過的話會生成一份保存當前用戶訊息的Session data與相對應的Session id
  3. 伺服器端在Response當中將Session Id返回並寫入用戶瀏覽器的Cookie當中
  4. 後續用戶透過該瀏覽器的請求都會自動攜帶包含Session Id的Cookie
  5. 伺服器端通過Request中的Session Id則可以找到之前保留的該用戶數據,從而獲取資訊。

但上述方式過於仰賴瀏覽器來保存Cookie,並且還需要額外在Server Side儲存User Session Data。

在現今的互聯網時代,有許許多多的Request來自非瀏覽器端,像是APP等,我們現今的前後端也慢慢地以分離式為主流並部署在不同的Port,甚至有時候還需要支援第三方登入,此時Cookie-Session方式就有點力不從心了。

https://ithelp.ithome.com.tw/upload/images/20211005/20129737aW6KstDck2.png

而JWT就是種基於Token的輕量級認證模式,Server Side通過認證後會生成一個JSON Object,並經過Signature得到一個Token再發回給User,此後User只要帶上此Token,Server Side就能解密得到該User資訊。相關流程如下

  1. 用戶在瀏覽器填寫帳號密碼並發送給伺服器端
  2. 伺服器端生成JWT Token,並返回給用戶
  3. 用戶在之後的Request都在Authorization header中,用Bearer schema帶上Token Authorization: Bearer <token>
  4. 伺服器端會進行Token驗證
  5. 驗證成功則開始執行該API所應該做的事,並返回正確的Response

https://ithelp.ithome.com.tw/upload/images/20211005/201297373qPHlgEs71.png

Token vs Cookie vs Session

Cookie

Cookie總是儲存在客戶端中,按在客戶端的儲存位置,可分為記憶體Cookie硬碟Cookie記憶體Cookie由瀏覽器維護,儲存在記憶體中,瀏覽器關閉後就消失了,其存在時間是短暫的。硬碟Cookie儲存在硬盤裡,有一個過期時間,除非使用者手工清理或到了過期時間,硬碟Cookie不會被刪除,其存在時間是長期的。所以,按存在時間,可分為 非持久Cookie和持久Cookie 。Cookie 是一個非常具體的東西,指的就是瀏覽器裡面能永久儲存的一種資料,僅僅是瀏覽器實現的一種資料儲存功能。

一言堂: Cookie是儲存在使用者瀏覽器端的資料,一般不超過4KB,主要記憶使用者的部分訊息,以此實現Session。

Session

Session字面意思是會話,主要用來標識自己的身份。比如在無狀態的api服務在多次請求資料庫時,如何知道是同一個使用者,這個就可以通過session的機制,伺服器要知道當前發請求給自己的是誰

為了區分客戶端請求, 服務端會給具體的客戶端生成身份標識session ,然後客戶端每次向伺服器發請求的時候,都帶上這個“身份標識”,伺服器就知道這個請求來自於誰了。

至於客戶端如何儲存該標識,可以有很多方式,對於瀏覽器而言,一般都是使用 cookie 的方式

伺服器使用session把使用者資訊臨時儲存了伺服器上,使用者離開網站就會銷燬,這種憑證儲存方式相對於cookie來說更加安全,但是session會有一個缺陷: 如果web伺服器做了負載均衡,那麼下一個操作請求到了另一臺伺服器的時候session會丟失。

因此,通常企業裡會使用 redis,memcached 快取中介軟體來實現session的共享,此時web伺服器就是一個完全無狀態的存在,所有的使用者憑證可以通過共享session的方式存取,當前session的過期和銷燬機制需要使用者做控制。

一言堂: Session即為儲存在伺服器端有時效性的資料,通常要透過Cookie來找到該User的Session。

Token

Token的意思是"令牌",是使用者身份的驗證方式,最簡單的token組成: Uid(使用者唯一標識) + Time(當前時間戳) + Sign(簽名,由token的前幾位加上以雜湊演算法壓縮成一定長度的十六進位制字串) ,同時還將不變的引數也放進Token。

一言堂: Token是一種在服務端不需要儲存用戶資料的身份驗證方式,有透過加密且無狀態並能接受所有域的請求。

Summary

這章節主要介紹JWT,讓大家知道JWT的結構、功能以及在Web使用JWT的認證流程,而在下章節會配合以前的Code去搭建JWT的Auth API,並加入JWT認證機制到現有的API之中。

Reference

https://kknews.cc/zh-tw/code/6653eqp.html


上一篇
Day19 Gin with Swagger
下一篇
Day21 Gin with JWT
系列文
fmt.Println("從零開始的Golang生活")30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言